package com.rlyy.rsj.job.remind;

import com.alibaba.fastjson.JSONObject;
import com.rlyy.rsj.common.JobConstans;
import com.rlyy.rsj.common.RemindType;
import com.rlyy.rsj.dao.RemindDao;
import com.rlyy.rsj.entity.*;
import com.rlyy.rsj.utils.RedisKeyFactory;
import com.rlyy.rsj.utils.RedisUtils;
import com.rlyy.rsj.utils.UniqueID;
import common.util.DateTimeFormatterUtil;
import common.util.emailUtils.EmailMessage;
import common.util.emailUtils.EmailUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 使用提醒
 *
 * @author shibixiao
 * @description :
 * @date 2021/07/21
 */
@Component
public class UsageRemind implements IRemind{

    private static final String FROM = "融联易云-融数聚";

    private static final String SUBJECT_TEMP = "融数聚-使用量提醒";

    @Autowired
    private RemindDao remindDao;
    
    @Override
    public boolean remindCondition(RemindEntity remindEntity, RemindTable remindInfo) {
        if(!JobConstans.REMIND_OPEN_YES.equals(remindInfo.getRemindOpen())){
            return false;
        }
        double remindPercent = remindInfo.getRemindCond()/100.0;
        remindEntity.setRemindCond(remindInfo.getRemindCond());
        remindEntity.setMailTemplate(remindInfo.getRemindTemplate());
        remindEntity.setRemindMode(remindInfo.getRemindMode());
        remindEntity.setSendTime(LocalDate.now());
        double percent = remindEntity.getOrgpUsePercent();
        //计算预警条件
        boolean isRemindCond = (1-percent) <= remindPercent;
        Map<Object, Object> remind = RedisUtils.hmget(RedisKeyFactory.wrapRemindKey(remindEntity.getOrgpId()+"_"+getRemindType().getCode()));
        if(CollectionUtils.isEmpty(remind)){
            return isRemindCond && remindInfo.getRemindFreq()>0 && remindInfo.getRemindNum()>0;
        }
        UsageRemindRedisValue remindRedisValue = JSONObject.parseObject(JSONObject.toJSONString(remind), UsageRemindRedisValue.class);
        return isRemindCond
                && remindInfo.getRemindFreq() <= remindRedisValue.getRemindTime().until(LocalDate.now(), ChronoUnit.DAYS)
                && remindInfo.getRemindNum() > remindRedisValue.getRemindNumbers();
    }

    @Override
    public void doRemind(RemindEntity remindEntity, ReceiveUser receiveUser) {
        List<Boolean> jobStatus = new ArrayList<>();
        String template = remindEntity.getMailTemplate();
        String mailContent = parseMailContent(remindEntity,template);
        mailContent = parseMailContent(receiveUser, mailContent);

        Set<String> remindModeSet =  Arrays.stream(remindEntity.getRemindMode().split(",")).collect(Collectors.toSet());

        //邮件预警
        if(remindModeSet.contains(JobConstans.REMIND_MODE_MAIL)){
            boolean sendStatus = false;
            String failReason = null;
            EmailMessage message = new EmailMessage();
            message.setContent(mailContent);
            message.setReceiveMailAccount(receiveUser.getReceiveUserEmail());
            message.setFrom(FROM);
            message.setSubject(SUBJECT_TEMP);

            try {
                EmailUtil.sendMail(message);
                logger.info("合同{}使用量不足{}，邮件已发送", remindEntity.getOrgpId(), remindEntity.getRemindCond());
                sendStatus = true;
            } catch (Exception e) {
                failReason = e.getMessage();
                logger.error("邮件发送失败，具体原因：", e);
            } finally {
                jobStatus.add(sendStatus);
                //TODO 记录日志
                RemindLogTable remindLog = RemindLogTable.builder()
                        .remindLogId(String.valueOf(UniqueID.generateId()))
                        .remindContent(mailContent)
                        .remindTm(LocalDateTime.now())
                        .remindMode(JobConstans.REMIND_MODE_MAIL)
                        .remindStatus(sendStatus?"1":"0")
                        .remindType(getRemindType().getCode())
                        .failReason(failReason)
                        .receiveUser(receiveUser.getReceiveUser()+":"+receiveUser.getReceiveUserEmail())
                        .build();
                remindDao.writeRemindLog(remindLog);
            }
        }
        //至少一种方式成功
        if(jobStatus.contains(Boolean.TRUE)) {
            // 更新redis
            RedisUtils.hincr(RedisKeyFactory.wrapRemindKey(remindEntity.getOrgpId() + "_" + getRemindType().getCode()), "remindNumbers", 1.0);
            RedisUtils.hset(RedisKeyFactory.wrapRemindKey(remindEntity.getOrgpId() + "_" + getRemindType().getCode()), "remindTime", DateTimeFormatterUtil.dateTimeToDate(LocalDateTime.now()));
        }
    }

    @Override
    public RemindType getRemindType() {
        return RemindType.USAGE;
    }

}
